# -*- coding: utf-8 -*-
import csv

"""
一、函数方法（list方法）
    csv.reader(f [, dialect='excel'][optional kwargs]) 
    #返回csv阅读器（迭代器）。f为打开csv文件的文件对象。dialect规定csv文件解析所采用的属性集，也可通过关键字参数修改指定属性。
    csv.writer(f [, dialect='excel'][optional kwargs])
    #返回csv写入器，其可将序列对象写入到csv文件中，写入方法为writerow()、writerows()，。

二、类方法（dict方法）
    csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds) 
    #建立类字典方式的csv阅读器（迭代器）。fieldnames为字典的key值（相当于列标题），每个key对应csv文件中的一列，如不指定，则默认读取的文件第一行元素为key。
    csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) 
    #建立类字典方式的csv写入器，具有writeheader()，writerrow(rowdict)，writerows(rowdicts)方法。

三、csv文件写入、读取都需要用到csv文件的属性集dialect（也可称之为方言），其主要包括：
    1.分隔符delimiter。用于将同一行中的各个数据分隔开，通常逗号，也有用tab的。
    2.换行符lineterminator。用于区分不同行的数据，通常为'\r\n'（操作系统原因，该换行符在写入csv时，可能会造成各行数据之间多出一个空行），也有用'\n'。
    3.引用符quotechar。用于引用包含特殊字符（如分隔符、引用符、换行符）的区域，通常为双引号（'"'）。
    4.转义符escapechar。用于在quoting设置为QUOTE_NONE时跳过转义符后的分隔符（即将该分隔符不作为分隔符，而是作为内容读入）、在doublequote设置为False时跳过转义符后的引用符（即将该引用符不作为引用符，而是作为内容读入）。
    5.引用模式quoting。指定特殊字符的表达形式。
        0表示csv.QUOTE_MINIMAL（最小引用，Excel生成的csv）。
        1表示csv.QUOTE_ALL（引用所有，Unix生成的csv）。
        2表示QUOTE_NONNUMERIC（引用非数字）。
        3表示csv.QUOTE_NONE（不引用，表示特殊字符是不被引用符包围的）。
    6.引用符引用模式doublequote。指定引用引用符自身的方式。
        True表示采用双重引用符形式（'""'）。
        False表示采用在引用符前置转义符的形式（如'\"'。注：如未同时设置escapechar，则将报错）。
    7.是否启用严格模式strict。如为True，则在读入的csv文件格式比较差时报错。通常采用默认的False。

四、csv模块已经内置了3个属性集：
    1.csv.excel：采用逗号分隔的Excel格式csv
        delimiter = ','
        doublequote = True
        lineterminator = '\r\n'
        quotechar = '"'
        quoting = 0
        skipinitialspace = False
        escapechar = None
    2.csv.excel_tab：采用tab分隔的Excel格式csv
        delimiter = '\t' #除分隔符外，其他继承自csv.excel类
    3.csv.unix_dialect：采用逗号分隔的Unix格式csv
        delimiter = ','
        doublequote = True
        lineterminator = '\n'
        quotechar = '"'
        quoting = 1
        skipinitialspace = False
        escapechar = None
    除此以外，用户自己也可通过csv.register_dialect()注册新的属性集，或者更简单地，在调用csv读写命令时，直接通过关键字参数指定各属性。
"""

# 读取csv
with open('data.csv', 'r', encoding='utf-8-sig') as f:
    # 使用utf-8时第一个单元格会出现'\ufeff'，要用utf-8-sig
    """1.列表形式读取
    ['序号', '姓名', '年龄']
    ['1', '张三', '21']
    ['2', '李四', '22']
    """
    data = csv.reader(f)
    for row in data:
        print(row)
    """2.字典形式读取
    {'序号': '1', '姓名': '张三', '年龄': '21'}
    {'序号': '2', '姓名': '李四', '年龄': '22'}
    """
    f.seek(0)
    data_2 = csv.DictReader(f)
    for i in data_2:
        print(i)

# 写入csv
with open('csv.csv', 'w', encoding='utf-8-sig') as f:
    # 方式一
    writer = csv.writer(f, lineterminator='\n')
    writer.writerow(('序号', '姓名', '年龄'))
    writer.writerows((('1', '张三', '21'), ('2', '李四', '22')))
    # 方式二
    writer_2 = csv.DictWriter(f, fieldnames=('序号', '姓名', '年龄'), lineterminator='\n')
    writer_2.writeheader()  # 将fieldnames写入标题行
    writer_2.writerow({'序号': '1', '姓名': '张三', '年龄': '21'})
    writer_2.writerows(({'序号': '2', '姓名': '李四', '年龄': '22'},))
